<script setup>
import { reactive, ref, onMounted, onBeforeUnmount, computed, watch } from 'vue'
import { ElMessage, ElBadge } from 'element-plus'
import axios from 'axios'

const form = reactive({ topic: 'server/public', qos: 2 })  // 默认QoS 2，确保消息可靠性
const subscribed = ref(false)
const messages = ref([])
const autoParse = ref(true) // 自动解析开关
const customScript = ref(`// 默认JSON解析脚本 - 可自动解析JSON格式消息
if (typeof data === 'string') {
  try {
    return JSON.parse(data);
  } catch (e) {
    // 非JSON格式返回原始消息
    return { parsed: false, original: data, type: 'text' };
  }
}
// 已为对象类型直接返回
return data;`) // 自定义解析脚本
const activeNames = ref({}) // 用于跟踪展开的折叠项
let ws

// 从localStorage加载设置
const loadSettings = () => {
  // 定义默认解析脚本
  const defaultScript = `// 默认JSON解析脚本
// 自动尝试将消息解析为JSON格式
if (typeof data === 'string') {
  try {
    return JSON.parse(data);
  } catch (e) {
    // 如果不是有效的JSON，返回原始字符串
    return { parsed: false, original: data, error: '不是有效的JSON格式' };
  }
}
// 如果已经是对象，直接返回
return data;`;
    
  const savedSettings = localStorage.getItem('subscribeSettings');
  if (savedSettings) {
    try {
      const settings = JSON.parse(savedSettings);
      form.topic = settings.topic || '';
      form.qos = settings.qos !== undefined ? settings.qos : 2;  // 默认QoS 2
      autoParse.value = settings.autoParse !== undefined ? settings.autoParse : true;
      // 如果没有保存的脚本，使用默认脚本
      customScript.value = settings.customScript || defaultScript;
    } catch (e) {
      console.error('Failed to load settings:', e);
      // 出错时使用默认解析脚本
      customScript.value = defaultScript;
    }
  } else {
    // 首次加载时使用默认解析脚本
    customScript.value = defaultScript;
  }
}

// 保存设置到localStorage
const saveSettings = () => {
  const settings = {
    topic: form.topic,
    qos: form.qos,
    autoParse: autoParse.value,
    customScript: customScript.value
  }
  localStorage.setItem('subscribeSettings', JSON.stringify(settings))
}

// 监听设置变化，自动保存
watch([() => form.topic, () => form.qos, autoParse, customScript], () => {
  saveSettings()
})

// 手动解析所有消息
const reparseAllMessages = () => {
  if (!customScript.value.trim()) {
    ElMessage.warning('请先编写解析脚本')
    return
  }

  // 重新解析所有消息
  const updatedMessages = messages.value.map(message => {
    if (message.type === 'message') {
      const parsedResult = parseMessage(message.message, 'json')
      return {
        ...message,
        parsedResult: parsedResult,
        parseError: parsedResult?.error || null
      }
    }
    return message
  })

  // 替换整个数组以触发响应式更新
  messages.value = updatedMessages

  ElMessage.success('重新解析完成')
  
  // 移动端振动反馈
  if (window.innerWidth <= 768 && 'vibrate' in navigator) {
    navigator.vibrate(100)
  }
}

// 解析单条消息
const parseSingleMessage = (message) => {
  if (!customScript.value.trim()) {
    ElMessage.warning('请先编写解析脚本')
    return
  }

  const parsedResult = parseMessage(message.message, 'json')

  // 找到消息在数组中的索引
  const index = messages.value.findIndex(m => m === message)
  if (index !== -1) {
    // 创建新的消息对象以触发响应式更新
    const updatedMessage = {
      ...message,
      parsedResult: parsedResult,
      parseError: parsedResult?.error || null
    }

    // 替换数组中的消息
    messages.value[index] = updatedMessage
  }

  ElMessage.success('消息解析完成')
  
  // 移动端振动反馈
  if (window.innerWidth <= 768 && 'vibrate' in navigator) {
    navigator.vibrate(100)
  }
}


const subscribe = async () => {
  try {
    await axios.post('/api/subscribe', form)
    ElMessage.success('已订阅: ' + form.topic)
    subscribed.value = true
    
    // 移动端振动反馈
    if (window.innerWidth <= 768 && 'vibrate' in navigator) {
      navigator.vibrate(100)
    }
  } catch (e) { 
    ElMessage.error('订阅失败: ' + (e?.response?.data?.message || e.message)) 
  }
}

const unsubscribe = async () => {
  try {
    await axios.post('/api/unsubscribe', { topic: form.topic })
    ElMessage.success('已取消: ' + form.topic)
    subscribed.value = false
    
    // 移动端振动反馈
    if (window.innerWidth <= 768 && 'vibrate' in navigator) {
      navigator.vibrate(100)
    }
  } catch (e) { 
    ElMessage.error('取消失败: ' + (e?.response?.data?.message || e.message)) 
  }
}

// 获取当前使用的解析脚本 - 直接返回用户输入的脚本内容
const getCurrentScript = () => {
  return customScript.value.trim()
}

// 解析消息内容 - 支持多种格式的消息解析，完全以用户输入的脚本为准
const parseMessage = (message, detectedType) => {
  if (!autoParse.value) {
    console.log('自动解析已关闭')
    return null
  }

  try {
    // 直接使用原始消息作为数据参数
    const data = message
    const script = getCurrentScript()
    
    console.log('检测到的消息类型:', detectedType)
    console.log('使用的解析脚本内容:', script)

    if (!script) {
      console.log('脚本为空，使用默认解析逻辑')
      // 使用默认的JSON解析作为后备
      try {
        return typeof data === 'string' ? JSON.parse(data) : data
      } catch (e) {
        return { error: '默认JSON解析失败', original: message }
      }
    }

    try {
      // 直接执行用户输入的脚本，传入data参数
      const fn = new Function('data', script)
      const result = fn(data)

      console.log('脚本执行结果:', result)

      // 检查结果是否有效
      if (result === undefined || result === null) {
        console.warn('脚本返回了无效结果，使用默认解析作为后备')
        try {
          return typeof data === 'string' ? JSON.parse(data) : data
        } catch (e) {
          return { original: message, parsed: false, warning: '脚本没有返回有效结果，保留原始消息' }
        }
      }

      return result
    } catch (scriptError) {
      console.error('脚本执行错误:', scriptError)
      // 提供更友好的错误信息，并尝试使用默认解析作为后备
      try {
        const fallbackResult = typeof data === 'string' ? JSON.parse(data) : data
        console.log('脚本执行失败，使用默认解析作为后备成功')
        return {
          ...fallbackResult,
          warning: '脚本执行失败，使用默认解析结果: ' + scriptError.message
        }
      } catch (fallbackError) {
        return { 
          error: '脚本执行错误: ' + scriptError.message,
          original: message,
          fallbackError: fallbackError.message
        }
      }
    }
  } catch (e) {
    console.error('解析过程发生错误:', e)
    return { error: '解析过程错误: ' + String(e), original: message }
  }
}

// 检测消息类型 - 支持多种格式
const detectMessageType = (message) => {
  // 如果是对象类型，检查特定属性
  if (typeof message === 'object' && message !== null) {
    if (message.type === 'csv') return 'csv'
    if (message.type === 'command') return 'command'
    if (message.type === 'text') return 'text'
    if (message.command) return 'command'
    return 'json'
  }
  
  // 处理字符串类型的消息
  if (typeof message === 'string') {
    // 尝试检测JSON格式
    try {
      const parsed = JSON.parse(message)
      if (typeof parsed === 'object' && parsed !== null) {
        return 'json'
      }
    } catch (e) {
      // 不是有效的JSON格式
    }
    
    // 检测CSV格式（简单检测：包含逗号和换行符的文本）
    if (message.includes(',') && (message.includes('\n') || message.includes('\r'))) {
      return 'csv'
    }
    
    // 检测是否为命令格式（以特定前缀开头）
    const commandPrefixes = ['command:', 'cmd:', 'execute:', 'run:']
    if (commandPrefixes.some(prefix => message.toLowerCase().startsWith(prefix))) {
      return 'command'
    }
    
    // 其他字符串都视为普通文本
    return 'text'
  }
  
  // 其他类型（数字、布尔值等）视为文本
  return 'text'
}

// 获取消息类型标签
const getMessageTypeLabel = (type) => {
  const labels = {
    'json': 'JSON 消息',
    'csv': 'CSV 数据',
    'command': '指令消息',
    'text': '文本消息',
    'unknown': '未知格式'
  }
  return labels[type] || '未知格式'
}

// 获取消息类型标签颜色
const getMessageTypeTagType = (type) => {
  const types = {
    'json': 'primary',
    'csv': 'success',
    'command': 'warning',
    'text': 'info',
    'unknown': 'danger'
  }
  return types[type] || 'danger'
}

// 调整移动端布局
const adjustLayoutForMobile = () => {
  // 可以在这里添加根据屏幕大小调整布局的逻辑
}

onMounted(() => {
  loadSettings()
  
  // 监听窗口大小变化，优化布局
  window.addEventListener('resize', adjustLayoutForMobile)
  
  // 初始化调用一次，确保正确的初始布局
  adjustLayoutForMobile()
  
  // WebSocket重连配置
  const reconnectInterval = ref(5000) // 5秒重连间隔
  const maxReconnectAttempts = ref(10) // 最大重连次数
  const reconnectAttempts = ref(0)
  
  const connectWebSocket = () => {
    try {
      // 自动检测环境并构建WebSocket URL
      let wsUrl = ''
      
      // 检查是否是ngrok环境
      const isNgrok = window.location.host.includes('ngrok')
      
      if (isNgrok) {
        // 在ngrok环境中，使用相对路径，通过Vite代理连接
        wsUrl = '/ws'
        console.log('使用ngrok环境的WebSocket相对路径:', wsUrl)
      } else {
        // 在本地环境中，直接连接到服务器的8081端口
        const protocol = 'ws:' // 本地环境始终使用ws协议
        const hostname = 'localhost' // 强制使用localhost而不是当前主机名
        wsUrl = `${protocol}//${hostname}:8081`
        console.log('使用本地环境的WebSocket URL:', wsUrl)
      }
      
      ws = new WebSocket(wsUrl)
      
      ws.onopen = () => {
        console.log('WebSocket连接已成功建立')
        reconnectAttempts.value = 0 // 重置重连计数
      }
      
      ws.onmessage = (ev) => {
        console.log('WebSocket收到消息:', ev.data)
        try {
          const data = JSON.parse(ev.data)
          console.log('解析后的消息数据:', data)
          
          if (data.type === 'message') {
            console.log('收到MQTT消息 - 主题:', data.topic, '内容:', data.message)
            console.log('自动解析状态:', autoParse.value, '解析脚本存在:', !!customScript.value.trim())
            
            // 自动检测消息类型
            const detectedType = detectMessageType(data.message)
            console.log('检测到的消息类型:', detectedType)

            // 强制进行解析，无论autoParse状态如何，确保消息至少被尝试解析
            let parsedResult = null
            let parseError = null
            
            try {
              // 首先尝试使用默认的JSON解析，这是最可靠的方式
              console.log('尝试默认JSON解析...')
              if (typeof data.message === 'string') {
                try {
                  parsedResult = JSON.parse(data.message)
                  console.log('默认JSON解析成功!')
                } catch (jsonError) {
                  console.log('默认JSON解析失败，尝试自定义脚本或保留原始消息:', jsonError.message)
                  // 即使JSON解析失败，也要保留原始消息作为结果
                  parsedResult = { original: data.message, isRawText: true }
                }
              } else {
                parsedResult = data.message
                console.log('消息已为对象类型，直接使用')
              }
              
              // 如果用户有自定义脚本且autoParse开启，使用自定义脚本
              if (autoParse.value && customScript.value.trim()) {
                console.log('使用自定义解析脚本...')
                try {
                  const customResult = parseMessage(data.message, detectedType)
                  if (!customResult?.error) {
                    parsedResult = customResult
                    console.log('自定义脚本解析成功!')
                  } else {
                    console.log('自定义脚本解析失败，保留默认解析结果')
                  }
                } catch (scriptError) {
                  console.error('自定义脚本执行异常:', scriptError)
                  // 保留默认解析结果
                }
              }
            } catch (parseException) {
              console.error('整体解析过程异常:', parseException)
              parsedResult = { original: data.message, parseError: parseException.message }
            }
            
            console.log('最终解析结果:', parsedResult)
            
            // 创建消息对象
            const message = {
              id: Date.now(),
              topic: data.topic,
              message: data.message,
              qos: data.qos,
              retained: data.retained,
              timestamp: new Date().toLocaleString(),
              type: detectedType,
              parsedResult: parsedResult,
              parseError: parseError,
              detectedType: detectedType,
              parseAttempted: true // 标记已尝试解析
            }
            
            // 添加到消息列表的开头
            messages.value.unshift(message)
            
            // 限制消息数量，防止内存溢出
            if (messages.value.length > 100) {
              messages.value = messages.value.slice(0, 100)
            }
          }
        } catch (e) {
          console.error('解析WebSocket消息失败:', e)
        }
      }
      
      // 添加错误处理和自动重连
      ws.onerror = (error) => {
        console.error('WebSocket错误:', error)
      }
      
      ws.onclose = () => {
        console.log('WebSocket连接已关闭')
        // 自动重连
        if (reconnectAttempts.value < maxReconnectAttempts.value) {
          reconnectAttempts.value++
          console.log(`尝试重连 (${reconnectAttempts.value}/${maxReconnectAttempts.value})...`)
          setTimeout(connectWebSocket, reconnectInterval.value)
        }
      }
    } catch (e) {
      console.error('WebSocket连接失败:', e)
    }
  }
  
  // 初始连接
  connectWebSocket()
  
  // 清理函数
  onBeforeUnmount(() => {
    ws && ws.close()
    window.removeEventListener('resize', adjustLayoutForMobile)
  })
})

// 统一格式化时间，避免中文时间被当成日期解析导致 NaN
const formatTimestamp = (ts) => {
  if (!ts) return ''
  // 如果已经是中文格式，直接返回
  if (typeof ts === 'string' && /\d{4}年\d{2}月\d{2}日/.test(ts)) return ts
  const d = new Date(ts)
  if (isNaN(d.getTime())) {
    // 兜底直接输出原值
    return typeof ts === 'string' ? ts : ''
  }
  // 使用本地格式，优化移动端显示
  const options = window.innerWidth <= 768 ? 
    { hour: '2-digit', minute: '2-digit', second: '2-digit' } : 
    { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }
  return d.toLocaleString('zh-CN', options)
}
</script>

<template>
  <el-card shadow="never" class="subscribe-card">
    <el-form label-width="80px" class="subscribe-form">
      <el-form-item label="主题">
        <el-input 
          v-model="form.topic" 
          placeholder="例如: test/topic"
          clearable
          size="large"
          @keyup.enter="subscribed ? unsubscribe : subscribe"
        />
      </el-form-item>
      <el-form-item label="QoS">
        <el-select v-model="form.qos" style="width:120px;" size="large">
          <el-option :value="0" label="0" />
          <el-option :value="1" label="1" />
          <el-option :value="2" label="2" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <div class="subscribe-buttons">
          <el-button 
            type="primary" 
            @click="subscribe" 
            :disabled="subscribed"
            size="large"
            class="primary-btn"
          >
            <i class="el-icon-plus"></i>
            订阅
          </el-button>
          <el-button 
            type="danger" 
            @click="unsubscribe" 
            :disabled="!subscribed"
            size="large"
            class="danger-btn"
          >
            <i class="el-icon-minus"></i>
            取消订阅
          </el-button>
        </div>
      </el-form-item>
    </el-form>
  </el-card>

  <!-- 自动解析配置 -->
  <el-card shadow="never" class="parse-config-card">
    <template #header>
      <div class="card-header">
        <h3 class="card-title">消息解析配置</h3>
        <el-switch 
          v-model="autoParse" 
          active-text="自动解析" 
          inactive-text="关闭"
          active-color="#409eff"
          inactive-color="#dcdfe6"
          class="parse-switch"
        />
      </div>
    </template>

    <el-form label-width="80px" v-if="autoParse">
      <el-form-item label="解析脚本">
        <el-input
          v-model="customScript"
          type="textarea"
          :rows="6"
          placeholder="自定义解析脚本..."
          size="large"
        />
      </el-form-item>
      <el-form-item>
        <el-button 
          type="primary" 
          @click="reparseAllMessages" 
          :disabled="!customScript.trim()"
          size="large"
          class="reparse-btn"
        >
          <i class="el-icon-refresh"></i>
          重新解析所有消息
        </el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card shadow="never" class="messages-card">
    <template #header>
      <div class="card-header">
        <h3 class="card-title">消息 <el-badge :value="messages.length" class="message-count" show-zero /></h3>
        <div class="parse-status-tags">
          <el-tag v-if="autoParse" type="success" size="small">自动解析已开启</el-tag>
          <el-tag v-else type="info" size="small">自动解析已关闭</el-tag>
        </div>
      </div>
    </template>
      <div v-if="messages.length === 0" class="empty-messages">
        <el-empty description="暂无消息" />
      </div>
      <el-timeline v-else class="messages-timeline" :reverse="true">
        <el-timeline-item 
          v-for="(m,idx) in messages" 
          :key="idx" 
          :timestamp="formatTimestamp(m.timestamp)"
          class="message-item"
        >
          <div class="message-container">
            <el-tag class="message-topic-tag" effect="light" size="small">
              {{ m.topic }}
            </el-tag>

            <!-- 消息类型指示器 -->
            <div class="message-info">
              <div class="message-tags">
                <el-tag 
                  :type="getMessageTypeTagType(m.detectedType)" 
                  size="small"
                  class="type-tag"
                >
                  {{ getMessageTypeLabel(m.detectedType) }}
                </el-tag>
                <el-tag 
                  v-if="m.parseError" 
                  type="danger" 
                  size="small" 
                  class="status-tag"
                >
                  解析错误
                </el-tag>
                <el-tag 
                  v-else-if="m.parsedResult" 
                  type="success" 
                  size="small" 
                  class="status-tag"
                >
                  解析成功
                </el-tag>
                <el-tag 
                  v-if="autoParse" 
                  type="info" 
                  size="small" 
                  class="status-tag"
                >
                  自定义脚本
                </el-tag>
              </div>
              <el-button
                type="primary"
                size="small"
                @click="parseSingleMessage(m)"
                :disabled="!customScript.trim()"
                class="reparse-single-btn"
              >
                <i class="el-icon-refresh"></i>
                重新解析
              </el-button>
            </div>

            <!-- 原始消息 -->
            <el-collapse class="message-details">
              <el-collapse-item title="原始消息" name="original" class="detail-item">
                <pre class="message-pre original-message">{{ typeof m.message==='object' ? JSON.stringify(m.message, null, 2) : m.message }}</pre>
              </el-collapse-item>

              <!-- 解析结果 - 总是显示，即使是原始消息 -->
              <el-collapse-item 
                title="解析结果" 
                name="parsed"
                class="detail-item"
              >
                <pre class="message-pre parsed-message">
                  {{ m.parsedResult ? JSON.stringify(m.parsedResult, null, 2) : JSON.stringify({ noParseResult: true, originalType: typeof m.message }, null, 2) }}
                </pre>
              </el-collapse-item>

              <!-- 解析错误 -->
              <el-collapse-item 
                v-if="m.parseError" 
                title="解析错误" 
                name="error"
                class="detail-item"
              >
                <el-alert 
                  :title="m.parseError" 
                  type="error" 
                  show-icon 
                  class="error-alert"
                />
              </el-collapse-item>
            </el-collapse>
          </div>
        </el-timeline-item>
      </el-timeline>
  </el-card>
</template>

<style scoped>
/* 全局样式 */
:root {
  --primary-color: #409eff;
  --success-color: #67c23a;
  --warning-color: #e6a23c;
  --danger-color: #f56c6c;
  --info-color: #909399;
  --border-color: #ebeef5;
  --background-color: #f5f7fa;
  --card-background: #ffffff;
  --text-primary: #303133;
  --text-regular: #606266;
  --text-secondary: #909399;
  --text-placeholder: #c0c4cc;
  --shadow-base: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
  --shadow-hover: 0 4px 20px 0 rgba(0, 0, 0, 0.12);
}

/* 卡片样式 */
.subscribe-card,
.parse-config-card,
.messages-card {
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 16px;
  transition: all 0.3s ease;
  background-color: var(--card-background);
  border: 1px solid var(--border-color);
}

.subscribe-card:hover,
.parse-config-card:hover,
.messages-card:hover {
  box-shadow: var(--shadow-hover);
  transform: translateY(-2px);
}

/* 卡片头部样式 */
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background-color: #fafafa;
}

.card-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}

/* 表单样式 */
.subscribe-form {
  padding: 16px 20px;
}

.subscribe-form :deep(.el-form-item) {
  margin-bottom: 20px;
}

.subscribe-form :deep(.el-form-item__label) {
  font-weight: 500;
  color: var(--text-regular);
}

/* 按钮样式 */
.subscribe-buttons {
  display: flex;
  gap: 12px;
  width: 100%;
}

.primary-btn,
.danger-btn {
  flex: 1;
  min-height: 40px;
  font-weight: 500;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.primary-btn:active,
.danger-btn:active {
  transform: scale(0.98);
}

.reparse-btn {
  width: 100%;
  min-height: 40px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.reparse-btn:active {
  transform: scale(0.98);
}

.reparse-single-btn {
  transition: all 0.3s ease;
  padding: 4px 12px;
}

.reparse-single-btn:active {
  transform: scale(0.95);
}

/* 解析开关样式 */
.parse-switch {
  margin-left: 12px;
  transition: all 0.3s ease;
}

/* 消息区域样式 */
.messages-scrollbar {
  max-height: 60vh;
  min-height: 400px;
  padding: 16px 20px 16px 0;
}

.empty-messages {
  margin: 60px 0;
  text-align: center;
}

.messages-timeline {
  margin-top: 16px;
}

.message-item {
  margin-bottom: 20px;
  animation: slideIn 0.5s ease-out;
}

.message-container {
  background-color: #fafafa;
  border-radius: 8px;
  padding: 16px;
  transition: all 0.3s ease;
}

.message-container:hover {
  background-color: #f0f2f5;
}

.message-topic-tag {
  display: block;
  text-align: center;
  margin-bottom: 12px;
  background-color: #f0f2f5;
  color: var(--primary-color);
  font-weight: 500;
  padding: 6px 12px;
  border-radius: 6px;
}

.message-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 8px;
}

.message-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.type-tag,
.status-tag {
  padding: 2px 8px;
  font-size: 12px;
  border-radius: 3px;
}

/* 消息详情样式 */
.message-details {
  border: 1px solid var(--border-color);
  border-radius: 6px;
  overflow: hidden;
}

.detail-item {
  border-radius: 6px;
  overflow: hidden;
}

.detail-item :deep(.el-collapse-item__header) {
  background-color: #fafafa;
  font-weight: 500;
  border-bottom: 1px solid var(--border-color);
  padding: 12px 16px;
  transition: all 0.3s ease;
}

.detail-item :deep(.el-collapse-item__header:hover) {
  background-color: #f5f7fa;
}

.detail-item :deep(.el-collapse-item__content) {
  padding: 12px 16px;
  background-color: #ffffff;
}

.message-pre {
  font-family: 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.6;
  margin: 0;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  padding: 12px;
  border-radius: 4px;
}

.original-message {
  background-color: #f5f7fa;
}

.parsed-message {
  background-color: #f0f9ff;
}

.error-alert {
  margin: 0;
}

/* 消息数量徽章 */
.message-count {
  margin-left: 8px;
  font-size: 12px;
  min-width: 20px;
  height: 20px;
  line-height: 20px;
  padding: 0;
}

/* 代码样式 */
code {
  background-color: #f5f7fa;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
}

/* 动画效果 */
@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 移动端优化 */
@media (max-width: 768px) {
  /* 整体布局调整 */
  .subscribe-card,
  .parse-config-card,
  .messages-card {
    border-radius: 16px;
    margin-bottom: 20px;
  }
  
  /* 卡片头部调整 */
  .card-header {
    padding: 16px;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .parse-switch {
    align-self: flex-end;
    transform: scale(1.3);
  }
  
  /* 表单调整 */
  .subscribe-form {
    padding: 16px;
  }
  
  .subscribe-form :deep(.el-form-item) {
    margin-bottom: 24px;
  }
  
  .subscribe-form :deep(.el-form-item__label) {
    font-size: 16px;
    font-weight: 500;
    color: var(--text-regular);
    margin-bottom: 8px;
    display: block;
  }
  
  .subscribe-form :deep(.el-input__inner) {
    min-height: 50px;
    font-size: 16px;
    padding: 0 16px;
  }
  
  .subscribe-form :deep(.el-select__wrapper) {
    min-height: 50px;
    font-size: 16px;
  }
  
  /* 按钮调整 */
  .subscribe-buttons {
    flex-direction: column;
    gap: 16px;
  }
  
  .primary-btn,
  .danger-btn,
  .reparse-btn {
    min-height: 56px;
    font-size: 18px;
    font-weight: 600;
  }
  
  /* 消息区域调整 */
  .messages-scrollbar {
    max-height: 45vh !important;
    min-height: 300px !important;
    padding: 16px 16px 16px 0;
  }
  
  .messages-timeline {
    padding-left: 12px;
  }
  
  .el-timeline :deep(.el-timeline-item__timestamp) {
    font-size: 13px;
    margin-top: 10px;
    color: var(--text-secondary);
    text-align: center;
  }
  
  .el-timeline :deep(.el-timeline-item__content) {
    padding-left: 16px;
    padding-bottom: 20px;
  }
  
  /* 消息容器调整 */
  .message-container {
    padding: 16px;
    border-radius: 12px;
  }
  
  .message-topic-tag {
    margin-bottom: 16px;
    padding: 8px 12px;
    font-size: 14px;
  }
  
  .message-info {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    margin-bottom: 16px;
  }
  
  .message-tags {
    justify-content: center;
    gap: 12px;
  }
  
  .type-tag,
  .status-tag {
    font-size: 14px;
    padding: 4px 10px;
  }
  
  .reparse-single-btn {
    width: 100%;
    min-height: 44px;
    font-size: 16px;
  }
  
  /* 消息详情调整 */
  .detail-item :deep(.el-collapse-item__header) {
    padding: 16px;
    font-size: 16px;
    font-weight: 500;
    height: auto;
    line-height: 1.5;
  }
  
  .detail-item :deep(.el-collapse-item__content) {
    padding: 16px;
  }
  
  .message-pre {
    font-size: 15px;
    line-height: 1.7;
    padding: 16px;
  }
  
  /* 空消息状态调整 */
  .empty-messages {
    margin: 80px 0;
  }
  
  .empty-messages :deep(.el-empty__description) {
    font-size: 16px;
    color: var(--text-secondary);
  }
  
  /* 改善滚动体验 */
  :deep(.el-scrollbar__wrap) {
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
  }
  
  /* 增加触摸区域 */
  .el-tag,
  .el-button {
    touch-action: manipulation;
  }
  
  /* 按钮脉冲效果 */
  .primary-btn,
  .danger-btn,
  .reparse-btn,
  .reparse-single-btn {
    position: relative;
    overflow: hidden;
  }
  
  .primary-btn::after,
  .danger-btn::after,
  .reparse-btn::after,
  .reparse-single-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 5px;
    height: 5px;
    background: rgba(255, 255, 255, 0.5);
    opacity: 0;
    border-radius: 100%;
    transform: scale(1, 1) translate(-50%, -50%);
    transform-origin: 50% 50%;
  }
  
  .primary-btn:active::after,
  .danger-btn:active::after,
  .reparse-btn:active::after,
  .reparse-single-btn:active::after {
    animation: ripple 0.65s ease-out;
  }
  
  @keyframes ripple {
    0% {
      transform: scale(0, 0);
      opacity: 0.5;
    }
    100% {
      transform: scale(20, 20);
      opacity: 0;
    }
  }
}

/* 桌面端优化 */
@media (min-width: 769px) {
  .subscribe-card,
  .parse-config-card,
  .messages-card {
    max-width: 800px;
    margin-left: auto;
    margin-right: auto;
  }
  
  .subscribe-buttons {
    max-width: 400px;
    margin: 0 auto;
  }
  
  .reparse-btn {
    max-width: 300px;
    margin: 0 auto;
  }
  
  .parse-status-tags {
    display: flex;
    gap: 8px;
  }
  
  .el-card :deep(.el-card__header) {
    padding: 16px 20px;
    background-color: #fafafa;
    border-bottom: 1px solid var(--border-color);
  }
  
  .el-card :deep(.el-card__body) {
    padding: 20px;
  }
}

/* 高DPI屏幕优化 */
@media (-webkit-min-device-pixel-ratio: 2) {
  .el-card :deep(.el-card__header),
  .detail-item :deep(.el-collapse-item__header) {
    border-bottom: 0.5px solid var(--border-color);
  }
  
  .message-details {
    border: 0.5px solid var(--border-color);
  }
}

/* 移除深色模式适配，保持白色背景 */
  </style>

